package cn.com.zero.front.auth.service.impl;

import cn.com.zero.api.auth.constant.HttpHeaderConstants;
import cn.com.zero.base.exception.ErrorCodeException;
import cn.com.zero.base.service.BaseService;
import cn.com.zero.base.util.SensitiveInfoUtil;
import cn.com.zero.common.auth.security.po.AuthUserPO;
import cn.com.zero.common.auth.security.vo.LoginUserInfoVO;
import cn.com.zero.file.service.IFileService;
import cn.com.zero.file.vo.FileInfo;
import cn.com.zero.front.auth.constant.FrontAuthConstants;
import cn.com.zero.front.auth.mapper.IRegisterMapper;
import cn.com.zero.front.auth.mapper.IUserLoginMapper;
import cn.com.zero.front.auth.mapper.IUserMapper;
import cn.com.zero.front.auth.po.UserInfoPO;
import cn.com.zero.front.auth.security.service.impl.LoginAuthenticationService;
import cn.com.zero.front.auth.service.IRegisterService;
import cn.com.zero.web.util.HttpRequestUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.Date;

/**
 * @author liuxh
 * @version 1.0.0
 * @Description 注册接口实现
 * @createTime 2023/3/29 17:14
 */
@Service
public class RegisterService extends BaseService implements IRegisterService {

    private LoginAuthenticationService loginAuthenticationService;
    private IUserMapper userMapper;
    private IUserLoginMapper userLoginMapper;
    private IFileService fileService;
    private IRegisterMapper registerMapper;


    @Transactional(rollbackFor = Throwable.class)
    @Override
    public UserInfoPO registerByMobile(String mobilePhone, String password) {
        String encryptMobile = SensitiveInfoUtil.encryptMobile(mobilePhone);
        AuthUserPO userByMobile = userMapper.getUserByNameOrMobile(encryptMobile);
        if (userByMobile != null) {
            throw new ErrorCodeException(-20000L); // 手机号验重失败
        }
        UserInfoPO userInfoPO = new UserInfoPO();
        // 获取用户ID
        String userId = generateUserId();
        userInfoPO.setUserId(userId);
        userInfoPO.setMobile(encryptMobile);
        String showMobile = SensitiveInfoUtil.encodeMobile(mobilePhone);
        userInfoPO.setShowMobile(showMobile);

        if (StringUtils.hasLength(password)) {
            // 密码加密
            String encryptPwd = SensitiveInfoUtil.encryptPwd(password);
            userInfoPO.setPassword(encryptPwd);
        }
        registerMapper.addUser(userInfoPO);
        return userInfoPO;
    }


    @Transactional(rollbackFor = Throwable.class)
    @Override
    public UserInfoPO registerByUserName(String userName, String password, MultipartFile avatar) {
        // 用户名称验重
        AuthUserPO userByName = userMapper.getUserByNameOrMobile(userName);
        if (userByName != null) {
            throw new ErrorCodeException(-20002L); // 用户名称验重失败
        }
        UserInfoPO userInfoPO = new UserInfoPO();
        // 获取用户ID
        String userId = generateUserId();
        userInfoPO.setUserId(userId);
        userInfoPO.setUserName(userName);
        // 密码加密
        String encryptPwd = SensitiveInfoUtil.encryptPwd(password);
        userInfoPO.setPassword(encryptPwd);
        // 上传图片
        if (avatar != null) {
            FileInfo fileInfo = fileService.upload(avatar, FrontAuthConstants.RELATIVE_PATH_AVATAR);
            userInfoPO.setAvatar(fileInfo.getRelativeFilePath());
        }
        registerMapper.addUser(userInfoPO);
        return userInfoPO;
    }

    /**
     * 登录
     *
     * @param userInfoPO 用户信息
     */
    @Override
    public LoginUserInfoVO loginUser(UserInfoPO userInfoPO) {
        AuthUserPO userPO = new AuthUserPO();
        userPO.setUserId(userInfoPO.getUserId());
        userPO.setUserName(userInfoPO.getUserName());
        userPO.setMobile(userInfoPO.getMobile());
        userPO.setPassword(userInfoPO.getPassword());
        userPO.setAccountNonExpired(true);
        userPO.setEnabled(true);
        String requestIp = HttpRequestUtil.getRequestIp();
        userPO.setLoginIp(requestIp);
        // 获取当前数据库时间
        Date currentTime = registerMapper.currentDate();
        userPO.setLoginTime(currentTime);
        String loginDevice = HttpRequestUtil.getHeader(HttpHeaderConstants.LOGIN_DEVICE_HEADER);
        userPO.setLoginDevice(loginDevice);
        // 保存用户信息到redis
        LoginUserInfoVO loginUserInfoVO = loginAuthenticationService.saveLoginUser(userPO, loginDevice);

        // 修改用户表登录信息
        userLoginMapper.modifyUserInfo(userPO);

        return loginUserInfoVO;
    }

    /**
     * 生成用户ID
     *
     * @return 用户ID
     */
    private String generateUserId() {
        String userId_pre = registerMapper.generateUserIdPre();
        String maxUserId = registerMapper.queryMaxUserId(userId_pre);
        String lastStr = "00";
        if (StringUtils.hasLength(maxUserId)) {
            // 获取最后两位
            String sub = StrUtil.sub(maxUserId, 18, 20);
            int lastNum = Integer.parseInt(sub) + 1;
            // 用户ID最后两位数格式化
            DecimalFormat df = new DecimalFormat("00");
            lastStr = df.format(lastNum);
        }
        return userId_pre + lastStr;
    }

    @Autowired
    public void setUserMapper(IUserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Resource
    public void setFileService(IFileService fileService) {
        this.fileService = fileService;
    }

    @Autowired
    public void setLoginAuthenticationService(LoginAuthenticationService loginAuthenticationService) {
        this.loginAuthenticationService = loginAuthenticationService;
    }

    @Autowired
    public void setRegisterMapper(IRegisterMapper registerMapper) {
        this.registerMapper = registerMapper;
    }

    @Autowired
    public void setUserLoginMapper(IUserLoginMapper userLoginMapper) {
        this.userLoginMapper = userLoginMapper;
    }
}
